<!DOCTYPE html>

<html lang="en">
<head>
	<meta charset="utf-8">
	<title>ScrollMagic Source: ScrollMagic/Scene/getters-setters.js</title>
	
  <script src="scripts/prettify/prettify.js"> </script>
  <script src="scripts/prettify/lang-css.js"> </script>
	<!--[if lt IE 9]>
	<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
	<![endif]-->
	<link type="text/css" rel="stylesheet" href="styles/sunlight.default.css">
	<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
	<link rel="shortcut icon" href="../assets/img/favicon.ico" type="image/x-icon">

	
	<link type="text/css" rel="stylesheet" href="styles/site.cosmo.css">
	
</head>

<body>
<div class="container-fluid">
	<div class="navbar navbar-fixed-top navbar-inverse">
		<div class="navbar-inner">
			<a class="brand" href="index.html">ScrollMagic</a>
			<ul class="nav">
				
				<li class="dropdown">
					<a href="classes.list.html" class="dropdown-toggle" data-toggle="dropdown">Classes<b
						class="caret"></b></a>

					<ul class="dropdown-menu ">
						
						<li>
							<a href="ScrollMagic.Controller.html">Controller</a>
						</li>
						
						<li>
							<a href="ScrollMagic.Scene.html">Scene</a>
						</li>
						

					</ul>
				</li>
				
				<li class="dropdown">
					<a href="events.list.html" class="dropdown-toggle" data-toggle="dropdown">Events<b
						class="caret"></b></a>

					<ul class="dropdown-menu ">
						
						<li>
							<a href="ScrollMagic.Scene.html#event:add">add</a>
						</li>
						
						<li>
							<a href="ScrollMagic.Scene.html#event:change">change</a>
						</li>
						
						<li>
							<a href="ScrollMagic.Scene.html#event:destroy">destroy</a>
						</li>
						
						<li>
							<a href="ScrollMagic.Scene.html#event:end">end</a>
						</li>
						
						<li>
							<a href="ScrollMagic.Scene.html#event:enter">enter</a>
						</li>
						
						<li>
							<a href="ScrollMagic.Scene.html#event:leave">leave</a>
						</li>
						
						<li>
							<a href="ScrollMagic.Scene.html#event:progress">progress</a>
						</li>
						
						<li>
							<a href="ScrollMagic.Scene.html#event:remove">remove</a>
						</li>
						
						<li>
							<a href="ScrollMagic.Scene.html#event:shift">shift</a>
						</li>
						
						<li>
							<a href="ScrollMagic.Scene.html#event:start">start</a>
						</li>
						
						<li>
							<a href="ScrollMagic.Scene.html#event:update">update</a>
						</li>
						

					</ul>
				</li>
				
				<li class="dropdown">
					<a href="mixins.list.html" class="dropdown-toggle" data-toggle="dropdown">Plugins<b
						class="caret"></b></a>

					<ul class="dropdown-menu ">
						
						<li>
							<a href="animation.GSAP.html">GSAP</a>
						</li>
						
						<li>
							<a href="animation.Velocity.html">Velocity</a>
						</li>
						
						<li>
							<a href="debug.addIndicators.html">addIndicators</a>
						</li>
						
						<li>
							<a href="framework.jQuery.html">jQuery</a>
						</li>
						

					</ul>
				</li>
				
			</ul>
		</div>
	</div>

	<div class="row-fluid">

		
			<div class="span12">
				
				<div id="main">
					


		<h1 class="page-title">Source: ScrollMagic/Scene/getters-setters.js</h1>
    
    <section>
        <article>
            <pre class="sunlight-highlight-javascript linenums">var _validate = _util.extend(SCENE_OPTIONS.validate, {
	// validation for duration handled internally for reference to private var _durationMethod
	duration : function (val) {
		if (_util.type.String(val) &amp;&amp; val.match(/^(\.|\d)*\d+%$/)) {
			// percentage value
			var perc = parseFloat(val) / 100;
			val = function () {
				return _controller ? _controller.info("size") * perc : 0;
			};
		}
		if (_util.type.Function(val)) {
			// function
			_durationUpdateMethod = val;
			try {
				val = parseFloat(_durationUpdateMethod.call(Scene));
			} catch (e) {
				val = -1; // will cause error below
			}
		}
		// val has to be float
		val = parseFloat(val);
		if (!_util.type.Number(val) || val &lt; 0) {
			if (_durationUpdateMethod) {
				_durationUpdateMethod = undefined;
				throw ["Invalid return value of supplied function for option \"duration\":", val];
			} else {
				throw ["Invalid value for option \"duration\":", val];
			}
		}
		return val;
	}
});

/**
 * Checks the validity of a specific or all options and reset to default if neccessary.
 * @private
 */
var validateOption = function (check) {
	check = arguments.length ? [check] : Object.keys(_validate);
	check.forEach(function (optionName, key) {
		var value;
		if (_validate[optionName]) { // there is a validation method for this option
			try { // validate value
				value = _validate[optionName](_options[optionName]);
			} catch (e) { // validation failed -> reset to default
				value = DEFAULT_OPTIONS[optionName];
				// (BUILD) - REMOVE IN MINIFY - START
				var logMSG = _util.type.String(e) ? [e] : e;
				if (_util.type.Array(logMSG)) {
					logMSG[0] = "ERROR: " + logMSG[0];
					logMSG.unshift(1); // loglevel 1 for error msg
					log.apply(this, logMSG);
				} else {
					log(1, "ERROR: Problem executing validation callback for option '" + optionName + "':", e.message);
				}
				// (BUILD) - REMOVE IN MINIFY - END
			} finally {
				_options[optionName] = value;
			}
		}
	});
};

/**
 * Helper used by the setter/getters for scene options
 * @private
 */
var changeOption = function(varname, newval) {
	var
		changed = false,
		oldval = _options[varname];
	if (_options[varname] != newval) {
		_options[varname] = newval;
		validateOption(varname); // resets to default if necessary
		changed = oldval != _options[varname];
	}
	return changed;
};

// generate getters/setters for all options
var addSceneOption = function (optionName) {
	if (!Scene[optionName]) {
		Scene[optionName] = function (newVal) {
			if (!arguments.length) { // get
				return _options[optionName];
			} else {
				if (optionName === "duration") { // new duration is set, so any previously set function must be unset
					_durationUpdateMethod = undefined;
				}
				if (changeOption(optionName, newVal)) { // set
					Scene.trigger("change", {what: optionName, newval: _options[optionName]});
					if (SCENE_OPTIONS.shifts.indexOf(optionName) > -1) {
						Scene.trigger("shift", {reason: optionName});
					}
				}
			}
			return Scene;
		};
	}
};

/**
 * **Get** or **Set** the duration option value.
 *
 * As a **setter** it accepts three types of parameters:
 * 1. `number`: Sets the duration of the scene to exactly this amount of pixels.  
 *   This means the scene will last for exactly this amount of pixels scrolled. Sub-Pixels are also valid.
 *   A value of `0` means that the scene is 'open end' and no end will be triggered. Pins will never unpin and animations will play independently of scroll progress.
 * 2. `string`: Always updates the duration relative to parent scroll container.  
 *   For example `"100%"` will keep the duration always exactly at the inner height of the scroll container.
 *   When scrolling vertically the width is used for reference respectively.
 * 3. `function`: The supplied function will be called to return the scene duration.
 *   This is useful in setups where the duration depends on other elements who might change size. By supplying a function you can return a value instead of updating potentially multiple scene durations.  
 *   The scene can be referenced inside the callback using `this`.
 *   _**WARNING:** This is an easy way to kill performance, as the callback will be executed every time `Scene.refresh()` is called, which happens a lot. The interval is defined by the controller (see ScrollMagic.Controller option `refreshInterval`).  
 *   It's recomended to avoid calculations within the function and use cached variables as return values.  
 *   This counts double if you use the same function for multiple scenes._
 *
 * @method ScrollMagic.Scene#duration
 * @example
 * // get the current duration value
 * var duration = scene.duration();
 *
 * // set a new duration
 * scene.duration(300);
 *
 * // set duration responsively to container size
 * scene.duration("100%");
 *
 * // use a function to randomize the duration for some reason.
 * var durationValueCache;
 * function durationCallback () {
 *   return durationValueCache;
 * }
 * function updateDuration () {
 *   durationValueCache = Math.random() * 100;
 * }
 * updateDuration(); // set to initial value
 * scene.duration(durationCallback); // set duration callback
 *
 * @fires {@link Scene.change}, when used as setter
 * @fires {@link Scene.shift}, when used as setter
 * @param {(number|string|function)} [newDuration] - The new duration setting for the scene.
 * @returns {number} `get` -  Current scene duration.
 * @returns {Scene} `set` -  Parent object for chaining.
 */

/**
 * **Get** or **Set** the offset option value.
 * @method ScrollMagic.Scene#offset
 * @example
 * // get the current offset
 * var offset = scene.offset();
 *
	 * // set a new offset
 * scene.offset(100);
 *
 * @fires {@link Scene.change}, when used as setter
 * @fires {@link Scene.shift}, when used as setter
 * @param {number} [newOffset] - The new offset of the scene.
 * @returns {number} `get` -  Current scene offset.
 * @returns {Scene} `set` -  Parent object for chaining.
 */

/**
 * **Get** or **Set** the triggerElement option value.
 * Does **not** fire `Scene.shift`, because changing the trigger Element doesn't necessarily mean the start position changes. This will be determined in `Scene.refresh()`, which is automatically triggered.
 * @method ScrollMagic.Scene#triggerElement
 * @example
 * // get the current triggerElement
 * var triggerElement = scene.triggerElement();
 *
	 * // set a new triggerElement using a selector
 * scene.triggerElement("#trigger");
	 * // set a new triggerElement using a DOM object
 * scene.triggerElement(document.getElementById("trigger"));
 *
 * @fires {@link Scene.change}, when used as setter
 * @param {(string|object)} [newTriggerElement] - The new trigger element for the scene.
 * @returns {(string|object)} `get` -  Current triggerElement.
 * @returns {Scene} `set` -  Parent object for chaining.
 */

/**
 * **Get** or **Set** the triggerHook option value.
 * @method ScrollMagic.Scene#triggerHook
 * @example
 * // get the current triggerHook value
 * var triggerHook = scene.triggerHook();
 *
	 * // set a new triggerHook using a string
 * scene.triggerHook("onLeave");
	 * // set a new triggerHook using a number
 * scene.triggerHook(0.7);
 *
 * @fires {@link Scene.change}, when used as setter
 * @fires {@link Scene.shift}, when used as setter
 * @param {(number|string)} [newTriggerHook] - The new triggerHook of the scene. See {@link Scene} parameter description for value options.
 * @returns {number} `get` -  Current triggerHook (ALWAYS numerical).
 * @returns {Scene} `set` -  Parent object for chaining.
 */

/**
 * **Get** or **Set** the reverse option value.
 * @method ScrollMagic.Scene#reverse
 * @example
 * // get the current reverse option
 * var reverse = scene.reverse();
 *
	 * // set new reverse option
 * scene.reverse(false);
 *
 * @fires {@link Scene.change}, when used as setter
 * @param {boolean} [newReverse] - The new reverse setting of the scene.
 * @returns {boolean} `get` -  Current reverse option value.
 * @returns {Scene} `set` -  Parent object for chaining.
 */

/**
 * **Get** or **Set** the loglevel option value.
 * @method ScrollMagic.Scene#loglevel
 * @example
 * // get the current loglevel
 * var loglevel = scene.loglevel();
 *
	 * // set new loglevel
 * scene.loglevel(3);
 *
 * @fires {@link Scene.change}, when used as setter
 * @param {number} [newLoglevel] - The new loglevel setting of the scene. `[0-3]`
 * @returns {number} `get` -  Current loglevel.
 * @returns {Scene} `set` -  Parent object for chaining.
 */

/**
 * **Get** the associated controller.
 * @method ScrollMagic.Scene#controller
 * @example
 * // get the controller of a scene
 * var controller = scene.controller();
 *
 * @returns {ScrollMagic.Controller} Parent controller or `undefined`
 */
this.controller = function () {
	return _controller;
};

/**
 * **Get** the current state.
 * @method ScrollMagic.Scene#state
 * @example
 * // get the current state
 * var state = scene.state();
 *
 * @returns {string} `"BEFORE"`, `"DURING"` or `"AFTER"`
 */
this.state = function () {
	return _state;
};

/**
 * **Get** the current scroll offset for the start of the scene.  
 * Mind, that the scrollOffset is related to the size of the container, if `triggerHook` is bigger than `0` (or `"onLeave"`).  
 * This means, that resizing the container or changing the `triggerHook` will influence the scene's start offset.
 * @method ScrollMagic.Scene#scrollOffset
 * @example
 * // get the current scroll offset for the start and end of the scene.
 * var start = scene.scrollOffset();
 * var end = scene.scrollOffset() + scene.duration();
 * console.log("the scene starts at", start, "and ends at", end);
 *
 * @returns {number} The scroll offset (of the container) at which the scene will trigger. Y value for vertical and X value for horizontal scrolls.
 */
this.scrollOffset = function () {
	return _scrollOffset.start;
};

/**
 * **Get** the trigger position of the scene (including the value of the `offset` option).  
 * @method ScrollMagic.Scene#triggerPosition
 * @example
 * // get the scene's trigger position
 * var triggerPosition = scene.triggerPosition();
 *
 * @returns {number} Start position of the scene. Top position value for vertical and left position value for horizontal scrolls.
 */
this.triggerPosition = function () {
	var pos = _options.offset; // the offset is the basis
	if (_controller) {
		// get the trigger position
		if (_options.triggerElement) {
			// Element as trigger
			pos += _triggerPos;
		} else {
			// return the height of the triggerHook to start at the beginning
			pos += _controller.info("size") * Scene.triggerHook();
		}
	}
	return pos;
};
</pre>
        </article>
    </section>





				</div>

				<div class="clearfix"></div>
				<footer>
					
					
		<span class="copyright">
		© Jan Paepke 2015
		</span>
					<br />
					
		<span class="jsdoc-message">
		Documentation generated by <a href="https://github.com/jsdoc3/jsdoc" target="_blank">JSDoc 3.5.5</a>
		using a customized version of the <a href="https://github.com/terryweiss/docstrap" target="_blank">DocStrap template</a>.
		</span>
				</footer>
			</div>

			
			<br clear="both">
		</div>

	</div>
	<script src="scripts/sunlight.js"></script>
	<script src="scripts/sunlight.javascript.js"></script>
	<script src="scripts/sunlight-plugin.doclinks.js"></script>
	<script src="scripts/sunlight-plugin.linenumbers.js"></script>
	<script src="scripts/sunlight-plugin.menu.js"></script>
	<script src="scripts/jquery.min.js"></script>
	<script src="scripts/jquery.scrollTo.js"></script>
	<script src="scripts/jquery.localScroll.js"></script>
	<script src="scripts/bootstrap-dropdown.js"></script>
	<script src="scripts/toc.js"></script>

	<script> prettyPrint(); </script>
	<script>  Sunlight.highlightAll({lineNumbers:true,  showMenu: true, enableDoclinks :true}); </script>

	<script>
		function openDeeplinkedElement (skipAni) {
			try {
				$("dt h4.member-collapsed").filter(window.location.hash.substring(1).replace(":", "\\:")).trigger("click", skipAni);
			} catch (e) {
				console.warn("ah ah ah! :p");
			}
		}
		$( function () {
			$( "#toc" ).toc( {
			    anchorName  : function(i, heading, prefix) {
					return $(heading).attr("id") || ( prefix + i );
				},
				selectors   : "h1:visible,h2:visible,h3:visible,h4:visible",
				onScrollFinish : openDeeplinkedElement,
				highlightOffset : 10,
				scrollOffset: 60
			} );
			$( "#toc>ul" ).addClass( "nav nav-pills nav-stacked" );
			$( "#main span[id^='toc']" ).addClass( "toc-shim" );

		} );
	</script>

	
	<script>
		$( function () {
			// $('#main').localScroll({
			// 	offset: { top: 56 } //offset by the height of your header (give or take a few px, see what works for you)
			// });
			// workaround for anchors below header...
			window.setTimeout(function () {
				$(document).scrollTop($(document).scrollTop()-60);
			}, 1)
			
			var hash = window.location.hash.substring(1).replace(":", "\\:");
			$( "dt h4.name" ).each( function () {
				var $this = $( this );
				var icon = $( "<i/>" ).addClass( "icon-plus-sign" ).addClass( "pull-right" ).addClass( "icon-white" );
				var dt = $this.parents( "dt" );
				var children = dt.next( "dd" );

				$this.append( icon ).css( {cursor : "pointer"} );
				$this.addClass( "member-collapsed" ).addClass( "member" );
				if (hash != $this.attr("id")) {
					children.hide();
				}
				$this.toggle( function (e, skipAni) {
					var scrollPos = $(document).scrollTop();
					window.location.hash = $(this).attr("id");
					$(document).scrollTop(scrollPos);
					icon.addClass( "icon-minus-sign" ).removeClass( "icon-plus-sign" ).removeClass( "icon-white" );
					$this.addClass( "member-open" ).removeClass( "member-collapsed" );
					children.slideDown(skipAni ? 0 : undefined);
				}, function () {
					icon.addClass( "icon-plus-sign" ).removeClass( "icon-minus-sign" ).addClass( "icon-white" );
					$this.addClass( "member-collapsed" ).removeClass( "member-open" );
					children.slideUp();
				} );
			} );
			// open if deeplinked
			if (hash.length > 0)
				openDeeplinkedElement(true);
		} );
	</script>
	

	<script type="text/javascript" src="../assets/js/tracking.js"></script>
</body>
</html>
